#pragma once

#include "stdafx.h"

/*
it's a common base class for all controls
when you need a whole new control
you should override the functions below
	------------------------------------
		draw
		in
		LButtonDown
		LButtonUp
		RButtonDown
		RButtonUp
		MouseMove
		MouseLeave
		KeyDown
		KeyUp
	------------------------------------
*/

class Control :public Graphical
{
protected:
	Shape * valid_region;

	virtual void determine_valid_region() = 0;

	unsigned int UID;
	std::string name;
public:
	Control() {}
	virtual ~Control() {}

	virtual void draw(Gdiplus::Graphics & graphics) override {}
	bool in(int x, int y)
	{
		return valid_region ? valid_region->in(x, y) : false;
	}

	virtual bool LButtonDown(int x, int y) { left_button_down(x, y); return true; }
	virtual bool LButtonUp(int x, int y) { left_button_up(x, y); return true; }
	virtual bool RButtonDown(int x, int y) { right_button_down(x, y); return true; }
	virtual bool RButtonUp(int x, int y) { right_button_up(x, y); return true; }
	virtual bool MouseMove(int button, int x, int y) { mouse_move(button, x, y); return true; }
	virtual bool MouseLeave(int button, int x, int y) { mouse_leave(button, x, y); return true; }
	virtual bool KeyDown(int keycode) { key_down(keycode); return true; }
	virtual bool KeyUp(int keycode) { key_up(keycode); return true; }
	virtual bool GetFocus() { get_focus(); return true; }
	virtual bool LostFocus() { lost_focus(); return true; }

	//below are variables need to be attributed----------------------------------
	std::function<void(int, int)> left_button_down = [](int, int) {};
	std::function<void(int, int)> left_button_up = [](int, int) {};
	std::function<void(int, int)> right_button_down = [](int, int) {};
	std::function<void(int, int)> right_button_up = [](int, int) {};
	std::function<void(int, int, int)> mouse_move = [](int, int, int) {};
	std::function<void(int, int, int)> mouse_leave = [](int, int, int) {};
	std::function<void(int)> key_down = [](int) {};
	std::function<void(int)> key_up = [](int) {};
	std::function<void()> get_focus = []() {};
	std::function<void()> lost_focus = []() {};
	//---------------------------------------------------------------------------

	void set_valid_region(Shape * region)
	{
		valid_region = region;
	}

	bool focused;
	Gdiplus::Graphics * graphics = nullptr;
};